using System;
using System.Linq;
using TEngine;
using static GameLogic.SocketAPI;

namespace GameLogic
{
    //网络质量
    public enum NetworkQuality
    {
        /// <summary>
        /// 极好
        /// </summary>
        Excellent,
        /// <summary>
        /// 良好
        /// </summary>
        Good,
        /// <summary>
        /// 正常
        /// </summary>
        Average,
        /// <summary>
        /// 不良
        /// </summary>
        Poor,
        /// <summary>
        /// 未知
        /// </summary>
        Unknown
    }

    public interface ISocketProxy
    {
        public void SendSocketData(SendPack packet);
    }

    public partial class SocketProxy : Module, ISocketProxy
    {
        SocketManager _socketManager = new SocketManager();

        NetworkQuality networkQuality = NetworkQuality.Unknown;

        public override void OnInit()
        {
            _socketManager.OnGetSocketData += OnGetSocketData;
            _socketManager.OnUpdateNetInfo += OnUpdateNetInfo;
            _socketManager.OnSocketClosed += OnSocketClosed;

            _socketManager.Open();
        }

        public override void Shutdown()
        {
            
        }

        public void OnSocketClosed(string msg)
        {
            

        }

        public void OnUpdateNetInfo(float crtPing, float avgPing)
        {
            networkQuality = NetworkQuality.Excellent;
            if (avgPing > 60) networkQuality = NetworkQuality.Good;
            if (avgPing > 120) networkQuality = NetworkQuality.Average;
            if (avgPing > 180) networkQuality = NetworkQuality.Poor;

            GameEvent.Get<ISocket>().OnNetStatusChanged(networkQuality);

            //Log.Info($"OnUpdatePingValue crtPing: {crtPing}ms, avgPing：{avgPing}ms，quality:{networkQuality}");
        }

        public void OnGetSocketData(uint cmdId, byte[] data, NewHeadReceive head)
        {
            SocketGetAPI.TryGetValue(APIGenerator((API_ID_BASE)cmdId), out var def);
            if (def == null) SocketGetAPI.TryGetValue(APIGenerator((API_ID_MATCH)cmdId), out def);
            if (def == null) SocketGetAPI.TryGetValue(APIGenerator((API_ID_AGENT)cmdId), out def);
            if (def == null)
            {
                Log.Warning("收到未知包 cmdId:0x{0:X}", cmdId);
            }
            else
            {
                Log.Info("收到{0}包，类:{1}", def.Name, def.Pakcet.Name);
                ReceivePack packet = (ReceivePack)Activator.CreateInstance(def.Pakcet);
                switch (cmdId)
                {
                    case (uint)API_ID_BASE.BUILD_LINK:
                        {
                            SendSocketData(new BuildLinkPacket());
                            SendSocketData(new GetAnonymousIDPacket()
                            {
                                //版本号待完善后修改，TODO
                                unityVersion = 7455,
                                time = GameUtility.LongToUint(DateTimeOffset.UtcNow.ToUnixTimeMilliseconds())
                            });
                        }
                        break;
                    case (uint)API_ID_BASE.ON_GET_ANONYMOUS_ID:
                        {
                            OnGetAnonymousIDPacket p = (OnGetAnonymousIDPacket)packet;
                            p.Read(data);
                            Log.Info("反馈-获取匿名访问anonymousID:{0}", p.anonymousID);
                        }
                        break;
                    case (uint)API_ID_BASE.ON_SOCKET_LOGIN:
                        {
                            OnSocketLoginPacket onSocketLoginPacket = (OnSocketLoginPacket)packet;
                            onSocketLoginPacket.Read(data);
                            Log.Info("反馈-登录 结果:{0},用户id:{1}。", head.dwParam == 0, onSocketLoginPacket.uID);
                        }
                        break;
                    case (uint)API_ID_AGENT.ON_USER_EXTRA_INFO:
                        {
                            OnUserExtraInfoPacket p = (OnUserExtraInfoPacket)packet;
                            p.Read(data);
                            Log.Info("用户额外信息");
                        }
                        break;

                    case (uint)API_ID_AGENT.AGENT_DATA_PUSH_INFO:
                        {
                            OnAgentDataPushPacket p = (OnAgentDataPushPacket)packet;
                            p.Read(data);
                            Log.Info("数值推送:{0}", p.extraData);
                        }
                        break;
                    case (uint)API_ID_AGENT.DRESS_INFO:
                        {
                            DressInfoPakcet p = (DressInfoPakcet)packet;
                            p.Read(data);
                            Log.Info("装扮信息:{0}", p.dressJsonStr);
                        }
                        break;
                }

                GameEvent.Get<ISocket>().OnGetSocketData(cmdId, packet, head);
            }
        }
        
        /// <summary>
        /// 统一处理common发包
        /// </summary>
        /// <param name="cmdId"></param>
        /// <param name="data"></param>
        public void SendSocketData(SendPack packet)
        {
            if (packet == null) return;
            uint cmdId = packet.CmdID;
            SocketSendAPI.TryGetValue(APIGenerator((API_ID_BASE)cmdId), out var def);
            if (def == null) SocketSendAPI.TryGetValue(APIGenerator((API_ID_MATCH)cmdId), out def);
            if (def == null) SocketSendAPI.TryGetValue(APIGenerator((API_ID_AGENT)cmdId), out def);
            if (def == null)
            {
                Log.Warning("发送未知包 cmdId:0x{0:X}", cmdId);
            }
            else
            {
                //实际上SocketSendAPI中的def值暂时没用到，TODO
                byte[] d = SendPack.SerializePacket(packet);
                _socketManager.Send(d);
                Log.Info("发送{0}包，类:{1}，值:{2}", def.Name, def.Pakcet.Name, string.Join(" ", d.Select(b => b.ToString())));
            }
        }
    }
}